﻿<template>
  <div>
    <el-dialog v-drag title = '导入文件' :visible.sync = 'dialogSelectVisible' width = '40%'
    @close = "resetUpload" append-to-body :close-on-click-modal = 'false' :close-on-press-escape = 'false'>
      <div v-loading = 'loading' :element-loading-text = 'loadingText'>
        <el-upload ref = 'upload' :action = 'actionUrl' :auto-upload = "false" :file-list = 'fileList'
        :limit='1' :on-exceed = 'onExceed' :http-request = "submitUpload" drag>
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        </el-upload>
        <div style = 'text-align: center; margin-top: 10px;'>
          <el-button type="info" @click = "resetUpload">取 消</el-button>
          <el-button type="primary" @click = "sureUpload">确 定</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import axios from 'axios'
export default {
  props: ['showImportDialog', 'currentEventsObj'],
  data () {
    return {
      loading: false,
      loadingText: '文件上传中...',
      dialogSelectVisible: false,
      // 上传文件部分
      actionUrl: `${$URL.IMG_UPLOAD_URL}`,
      fileList: [],
      fileReader: '',
      fileName: '',
      fileContent: '',
      // 事件的请求和响应的数据----api的键/页面展示的键/值/事件编号
      // inputArray----apiKey/pageKey/eventNo
      // outputArray----apiKey/pageKey/value/eventNo
      pagePrimaryObj: {
        inputArray: [],
        outputArray: []
      }
    }
  },
  created () {
    this.initPage()
  },
  mounted () {
    if (!window.FileReader) {
      this.$message({
        message: '您的浏览器不支持 FileReader API',
        type: 'warning'
      })
    } else {
      this.fileReader = new FileReader()
    }
  },
  methods: {
    // 初始化页面信息
    initPage () {
      this.pagePrimaryObj = {
        inputArray: [],
        outputArray: []
      }
      this.fileContent = ''
      this.fileName = ''
      this.fileList = []
    },
    // 文件超过最大上传个数时
    onExceed (files, fileList) {
      this.$message({
        message: '一次只能上传一个文件，请先移除文件列表中的文件，再选择需要上传的文件',
        type: 'warning'
      })
    },
    // 根据事件编号获取该事件的key值
    getEventKeyByEventNo (targetEventNo) {
      // 每次将this.pagePrimaryObj.inputArray清空
      this.pagePrimaryObj.inputArray = []
      if (this.currentEventsObj && !this.$isEmptyObject(this.currentEventsObj) && this.currentEventsObj.inputDic) {
        // 输入的参数格式为：api中的键名 = 页面展示的键名
        for (let i = 0; i < this.currentEventsObj.inputDic.length; i++) {
          if (this.currentEventsObj.inputDic[i].inputKey.indexOf('=') !== -1) {
            let dicInputArray = this.currentEventsObj.inputDic[i].inputKey.split('=')
            let obj = {
              apiKey: dicInputArray[0],
              pageKey: dicInputArray[1],
              eventNo: targetEventNo
            }
            this.pagePrimaryObj.inputArray.push(obj)
          }
        }
      }
    },
    // 根据事件编号获取事件的详细
    getEventsInfoByEventNo (eventItemNo) {
      this.loading = true
      this.loadingText = '文件上传中...'
      // 获取该事件的key值
      this.getEventKeyByEventNo(eventItemNo)
      // 获取事件的详细
      this.$get('/events4dform/' + eventItemNo).then(data => {
        let dataInfo = data.data.result
        if (dataInfo.code === 'failed') {
          this.$message({
            message: dataInfo.msg,
            type: 'error'
          })
          this.loading = false
        }
        if (dataInfo.code === 'success') {
          let currentEventInfo = {
            no: dataInfo.data.no,
            name: dataInfo.data.name,
            category: dataInfo.data.category,
            request_parameters: dataInfo.data.request_parameters,
            response_data: dataInfo.data.response_data
          }
          let parametersObj = JSON.parse(dataInfo.data.request_parameters)
          let isLocalEvent = false
          // 判断事件的类型，RequestUrl是以~开头的是本地事件，否则是http事件
          if (parametersObj.RequestUrl.indexOf('~') === 0) {
            isLocalEvent = true
          }
          this.changeEventsInfoBeforeSubmit(eventItemNo, currentEventInfo, isLocalEvent)
        }
      }).catch(error => {
        this.loading = false
        this.$message({
          message: error,
          type: 'error'
        })
      })
    },
    // 修改输入参数的公共方法
    getInputParamsMethods (pageKey) {
      let inputKeyValue = ''
      if (pageKey.indexOf('@') === 0) {
        inputKeyValue = pageKey.slice(1)
      } else if (pageKey === '$_login_id') {
        inputKeyValue = this.$store.state.nameId
      } else if (pageKey === '$_login_name' || pageKey === '$_user_name') {
        inputKeyValue = this.$store.state.userName
      } else if (pageKey === '$_now') {
        inputKeyValue = new Date()
      } else if (pageKey === '$_user_no') {
        inputKeyValue = this.$store.state.userNo
      } else if (pageKey === '$_file_name') {
        inputKeyValue = this.fileName
      } else if (pageKey === '$_file_content') {
        inputKeyValue = this.fileContent
      }
      return inputKeyValue
    },
    // 修改事件的参数----主要是需要修改事件path、search、postData等参数
    changeEventsInfoBeforeSubmit (eventItemNo, currentEventInfo, isLocalEvent) {
      // 获取触发事件的parameters
      let evalParamters = {}
      if (this.pagePrimaryObj.inputArray.length) {
        this.pagePrimaryObj.inputArray.forEach(item => {
          // 找到该事件对应的参数
          if (item.eventNo === eventItemNo) {
            // 判断apiKey是否是 Query.key的结构（Query表示的是字段名，key表示的是该对象中的一个属性）
            if (item.apiKey.indexOf('.') !== -1) {
              let apiObjString = item.apiKey.split('.')
              // 需要先判断该对象是否已经存在于evalParamters中
              if (Object.keys(evalParamters).indexOf(apiObjString[0]) === -1) {
                evalParamters[apiObjString[0]] = {}
              }
              evalParamters[apiObjString[0]][apiObjString[1]] = this.getInputParamsMethods(item.pageKey)
            } else {
              evalParamters[item.apiKey] = this.getInputParamsMethods(item.pageKey)
            }
          }
        })
      }
      let toEvalMethodJsonString = this.$isEmptyObject(evalParamters) ? '' : evalParamters
      this.triggerEventMethod(eventItemNo, currentEventInfo, isLocalEvent, toEvalMethodJsonString)
    },
    // 触发事件
    triggerEventMethod (eventItemNo, currentEventInfo, isLocalEvent, toEvalMethodJsonString) {
      if (isLocalEvent) {
        this.$post('/events4dform/' + eventItemNo + '/eval', {
          this_data: '',
          parameters: toEvalMethodJsonString
        }).then(data => {
          let dataInfo = data.data.result
          this.loading = false
          if (dataInfo.code === 'failed') {
            this.$message({
              message: dataInfo.msg,
              type: 'error',
              duration: 5000
            })
            let content = decodeURIComponent(dataInfo.file)
            let blobContent = this.toBlob(content, dataInfo.filetype)
            this.downloadblob(blobContent, dataInfo.filename)
          } else if (dataInfo.code === 'success') {
            this.$message({
              message: '文件上传成功',
              type: 'success'
            })
            this.$refs.upload.clearFiles()
            this.$emit('closeUploadDialogSuccess')
          }
        }).catch(error => {
          this.loading = false
          this.$message({
            message: error,
            type: 'error'
          })
        })
      } else {
        let requestObj = JSON.parse(currentEventInfo.request_parameters)
        if (!this.$isEmptyObject(requestObj) && requestObj.RequestUrl && requestObj.RequestMethod) {
          let axiosUrl = requestObj.RequestUrl
          // 改变path
          if (requestObj.RequestPath && !this.$isEmptyObject(requestObj.RequestPath) && toEvalMethodJsonString) {
            // 获取请求的url中的path---将url中的变量的改为获取到的值
            for (let pathKey in requestObj.RequestPath) {
              for (let modelKey in toEvalMethodJsonString) {
                if (pathKey === modelKey) {
                  axiosUrl = axiosUrl.replace('{' + pathKey + '}', toEvalMethodJsonString[pathKey])
                }
              }
            }
          }
          // 修改query的值
          let axiosQuery = {}
          if (requestObj.RequestQueryString && !this.$isEmptyObject(requestObj.RequestQueryString) && toEvalMethodJsonString) {
            for (let searchKey in requestObj.RequestQueryString) {
              for (let parametersKey in toEvalMethodJsonString) {
                if (searchKey === parametersKey) {
                  axiosQuery[searchKey] = toEvalMethodJsonString[parametersKey]
                }
              }
            }
          }
          // 修改postData的值
          let axiosPostData = {}
          if (requestObj.RequestPostData && !this.$isEmptyObject(requestObj.RequestPostData) && toEvalMethodJsonString) {
            for (let postKey in requestObj.RequestPostData) {
              for (let parametersKey in toEvalMethodJsonString) {
                if (postKey === parametersKey) {
                  axiosPostData[postKey] = toEvalMethodJsonString[parametersKey]
                }
              }
            }
          }
          axios({
            url: axiosUrl,
            method: requestObj.RequestMethod,
            // headers: requestObj.RequestHeader,
            data: axiosPostData,
            params: axiosQuery
          }).then(data => {
            let dataInfo = data.data.result
            this.loading = false
            if (dataInfo.code === 'failed') {
              this.$message({
                message: dataInfo.msg,
                type: 'error',
                duration: 5000
              })
              let content = decodeURIComponent(dataInfo.file)
              let blobContent = this.toBlob(content, dataInfo.filetype)
              this.downloadblob(blobContent, dataInfo.filename)
            } else if (dataInfo.code === 'success') {
              this.$message({
                message: '文件上传成功',
                type: 'success'
              })
              this.$refs.upload.clearFiles()
              this.$emit('closeUploadDialog')
            }
          }).catch(error => {
            this.loading = false
            this.$message({
              message: error,
              type: 'error'
            })
          })
        }
      }
    },
    submitUpload (options) {
      this.loading = true
      this.loadingText = '文件上传中'
      let file = options.file
      this.fileName = file.name
      // let fileLength = file.size
      if (file) {
        this.fileReader.readAsDataURL(file)
      }
      this.fileReader.onload = () => {
        let base64Str = this.fileReader.result
        this.fileContent = base64Str.split(',')[1]
        this.getEventsInfoByEventNo(this.currentEventsObj.eventsNo)
      }
    },
    // 点击确定按钮时
    sureUpload () {
      this.$refs.upload.submit()
    },
    // 点击取消按钮时
    resetUpload () {
      this.$refs.upload.abort()
      this.$emit('closeUploadDialog')
      this.$refs.upload.clearFiles()
    },
    // 上传文件出错时，需要下载下来
    downloadblob (blobcontent, filename) {
      if ('msSaveOrOpenBlob' in navigator) {
        // Microsoft Edge and Microsoft Internet Explorer 10-11
        window.navigator.msSaveOrOpenBlob(blobcontent, filename)
      } else {
        // 创建隐藏的可下载链接
        var eleLink = document.createElement('a')
        eleLink.download = filename
        eleLink.style.display = 'none'
        // 字符内容转变成blob地址
        eleLink.href = URL.createObjectURL(blobcontent)
        // 触发点击
        document.body.appendChild(eleLink)
        eleLink.click()
        // 然后移除
        document.body.removeChild(eleLink)
      }
    },
    // 将base64装为文件
    toBlob (base64str, filetype) {
      let bytes = window.atob(base64str)
      let n = bytes.length
      let u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bytes.charCodeAt(n)
      }
      return new Blob([u8arr], {type: filetype})
    }
  },
  watch: {
    showImportDialog: {
      handler: function (val, oldVal) {
        this.dialogSelectVisible = val
        if (val) {
          this.initPage()
        }
      },
      deep: true
    }
  }
}
</script>
